/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.swak.monitor.dubbo.web;

import java.util.List;
import java.util.Map;

import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.springframework.beans.factory.annotation.Autowired;

import com.swak.annotation.Get;
import com.swak.annotation.Post;
import com.swak.annotation.RestApi;
import com.swak.monitor.dubbo.model.domain.MethodMetadata;
import com.swak.monitor.dubbo.model.dto.ServiceTestDTO;
import com.swak.monitor.dubbo.service.ProviderService;
import com.swak.monitor.dubbo.service.impl.GenericServiceImpl;
import com.swak.monitor.dubbo.utils.Constants;
import com.swak.monitor.dubbo.utils.ConvertUtil;
import com.swak.monitor.dubbo.utils.ServiceTestUtil;
import com.swak.utils.JsonMapper;

@RestApi(value = "DubboServiceTestApi", path = "/api/monitor/:env/test")
public class ServiceTestApi {

    @Autowired
    private GenericServiceImpl genericService;
    @Autowired
    private ProviderService providerService;

    @Post
    public Object test(String env, ServiceTestDTO serviceTestDTO) {
        try {
            return genericService.invoke(serviceTestDTO.getService(), serviceTestDTO.getMethod(),
                serviceTestDTO.getParameterTypes(), serviceTestDTO.getParams());
        } catch (Exception e) {
            throw e;
        }
    }

    @Get("/method")
    public MethodMetadata methodDetail(String env, String application, String service, String method) {
        Map<String, String> info = ConvertUtil.serviceName2Map(service);
        MetadataIdentifier identifier = new MetadataIdentifier(info.get(Constants.INTERFACE_KEY),
            info.get(Constants.VERSION_KEY), info.get(Constants.GROUP_KEY), Constants.PROVIDER_SIDE, application);
        String metadata = providerService.getProviderMetaData(identifier);
        MethodMetadata methodMetadata = null;
        if (metadata != null) {
            FullServiceDefinition serviceDefinition = JsonMapper.fromJson(metadata, FullServiceDefinition.class);
            List<MethodDefinition> methods = serviceDefinition.getMethods();
            if (methods != null) {
                for (MethodDefinition m : methods) {
                    if (ServiceTestUtil.sameMethod(m, method)) {
                        methodMetadata = ServiceTestUtil.generateMethodMeta(serviceDefinition, m);
                        break;
                    }
                }
            }
        }
        return methodMetadata;
    }
}
